//
// Created by EDZ on 2022/1/6.
//

#include "smart_pointers.h"
#include <iostream>

int Resource::getAge() const {
    return age;
}

Resource::Resource(int a) : age{a} {
    std::cout << "构造函数 Resource\n";
}

Resource::~Resource() {
    std::cout << "析构函数 ~Resource" << std::endl;
}

void Resource::setAge(int a) {
    age = a;
}

void func_smart_pointer_v2() {

};


void func_smart_pointer() {
    smart_ptr<Resource> res = new Resource(1);
    int age;
    std::cout << "请输入年龄: ";
    std::cin >> age;
    res->setAge(age);
    std::cout << "您输入的年龄是: " << res->getAge() << std::endl;

    if (res->getAge() < 10)
        throw std::out_of_range{
                "年龄不符合范围,抛出异常，"
                "smart_ptr<Resource> res 指针会自动执行析构\n"
                "不会造成内存泄露\n"
        };
}

void func_use_pointer() {
    int select;
    do {
        do {
            std::cout << ("请选择案例[1 智能指针] [2 普通指针] [3 智能指针v2]，输入：");
            std::cin >> select;
            if (std::cin.fail()) {
                std::cout<<"输入错误！\n";
                std::cin.clear();
                std::cin.sync();
                /// 必须忽略缓冲区，否则cin直接拿缓冲区内容，造成死循环。。
                std::cin.ignore();
            }
        } while (select!=1 && select!=2 && select!=3);

        try {
            if (select == 1) {
                func_smart_pointer();
            } else if (select == 2) {
                func_unsafe_pointer();
            } else if (select == 3) {
                func_smart_pointer_v2();
            }
        } catch (std::out_of_range &err) {
            puts(err.what());
        }
        std::cout << ("请决定是否退出 (Y/N) ? ");
        char chr;
        std::cin >> chr;
        if (std::cin.fail()) {
            std::cin.clear();
            std::cin.sync();
            /// 必须忽略缓冲区，否则cin直接拿缓冲区内容，造成死循环。。
            std::cin.ignore();
            std::cout << "读取cin错误:" << std::endl;
        }
        std::cout << chr << "=" << chr << std::endl;
        if ( chr == 'y' || chr == 'Y') {
            break;
        }
    } while (true);
}

/// 会泄露内存，由于提前抛出异常
void func_unsafe_pointer() {
    Resource *r = new Resource(0);
    int age;
    std::cout << "请输入年龄: ";
    std::cin >> age;
    r->setAge(age);
    std::cout << "您输入的年龄是: " << r->getAge() << std::endl;

    if (r->getAge() < 10)
        throw std::out_of_range{"年龄不符合范围,抛出异常，*r 指针会造成内存泄露"};
    delete r;
}
